package com.batchengine.cron;

/**
 * Created by sunil.incubator@yahoo.com.
 * User: sunil.kalva
 * Date: Jul 22, 2009
 */
public class CronUtil {

    public static final int SUNDAY = 1;

    public static final int MONDAY = 2;

    public static final int TUESDAY = 3;

    public static final int WEDNESDAY = 4;

    public static final int THURSDAY = 5;

    public static final int FRIDAY = 6;

    public static final int SATURDAY = 7;

    public static final int LAST_DAY_OF_MONTH = -1;

    public static final long MILLISECONDS_IN_MINUTE = 60l * 1000l;

    public static final long MILLISECONDS_IN_HOUR = 60l * 60l * 1000l;

    public static final long SECONDS_IN_DAY = 24l * 60l * 60L;

    public static final long MILLISECONDS_IN_DAY = SECONDS_IN_DAY * 1000l;

    private CronUtil() {
    }

    public static void validateDayOfWeek(int dayOfWeek) {
        if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) {
            throw new IllegalArgumentException("Invalid day of week.");
        }
    }

    public static void validateHour(int hour) {
        if (hour < 0 || hour > 23) {
            throw new IllegalArgumentException("Invalid hour (must be >= 0 and <= 23).");
        }
    }

    public static void validateMinute(int minute) {
        if (minute < 0 || minute > 59) {
            throw new IllegalArgumentException("Invalid minute (must be >= 0 and <= 59).");
        }
    }

    public static void validateSecond(int second) {
        if (second < 0 || second > 59) {
            throw new IllegalArgumentException("Invalid second (must be >= 0 and <= 59).");
        }
    }

    public static void validateDayOfMonth(int day) {
        if ((day < 1 || day > 31) && day != LAST_DAY_OF_MONTH) {
            throw new IllegalArgumentException("Invalid day of month.");
        }
    }

    public static void validateMonth(int month) {
        if (month < 1 || month > 12) {
            throw new IllegalArgumentException("Invalid month (must be >= 1 and <= 12.");
        }
    }

    public static void validateYear(int year) {
        if (year < 1970 || year > 2099) {
            throw new IllegalArgumentException("Invalid year (must be >= 1970 and <= 2099.");
        }
    }

    /**
     * <p>
     * Make a trigger that will fire every day at the given time.
     * </p>
     * <p/>
     * <p>
     * The generated trigger will still need to have its name, group,
     * start-time and end-time set.
     * </p>
     *
     * @param dayOfWeek (1-7) the day of week upon which to fire
     * @param hour      the hour (0-23) upon which to fire
     * @param minute    the minute (0-59) upon which to fire
     * @see #SUNDAY
     * @see #MONDAY
     * @see #TUESDAY
     * @see #WEDNESDAY
     * @see #THURSDAY
     * @see #FRIDAY
     * @see #SATURDAY
     * @deprecated use org.quartz.TriggerUtils instead!
     */
    public static String makeWeeklyExpression(int dayOfWeek, int hour, int minute) {

        validateDayOfWeek(dayOfWeek);
        validateHour(hour);
        validateMinute(minute);

        try {

            return "0 " + minute + " " + hour + " ? * " + dayOfWeek;
        } catch (Exception ignore) {
            return null; /* never happens... */
        }
    }

    /**
     * <p>
     * Make a trigger that will fire every day at the given time.
     * </p>
     * <p/>
     * <p>
     * The generated trigger will still need to have its name, group,
     * start-time and end-time set.
     * </p>
     * <p/>
     * <p>
     * If the day of the month specified does not occur in a given month, a
     * firing will not occur that month. (i.e. if dayOfMonth is specified as
     * 31, no firing will occur in the months of the year with fewer than 31
     * days).
     * </p>
     *
     * @param dayOfMonth (1-31, or -1) the day of week upon which to fire
     * @param hour       the hour (0-23) upon which to fire
     * @param minute     the minute (0-59) upon which to fire
     * @deprecated use org.quartz.TriggerUtils instead!
     */
    public static String makeMonthlyTrigger(int dayOfMonth, int hour, int minute) {

        validateDayOfMonth(dayOfMonth);
        validateHour(hour);
        validateMinute(minute);

        try {
            if (dayOfMonth != LAST_DAY_OF_MONTH) {
                return String.format("0 %s %s %s * ?", minute, hour, dayOfMonth);
            } else {
                return String.format("0 %s %s L * ?", minute, hour);
            }
        } catch (Exception ignore) {
            return null; /* never happens... */
        }
    }


}
